#pragma once
#include "sstream.h"
using namespace std;

#define Tnline template<typename T> inline

class Where 
{
protected:
	sstream _ss;
public:
	inline string data(void)const;
	inline Where& clear(void);
	inline Where& operator<<(const string& expr);
	Tnline Where& AND(const string& name, const string& op, T value);
	Tnline Where& OR(const string& name, const string& op, T value);
};

inline string Where::data(void)const
{
	if(_ss.str().empty())
	{
		return ";";
	}
	return " WHERE " + _ss.str();
}
inline Where& Where::clear(void)
{
	_ss.str(); 
	return *this;
}
inline Where& Where::operator<<(const string& expr)
{
	_ss << expr;
	return *this;
}
Tnline Where& Where::AND(const string& name, const string& op, T value)
{
	if(_ss.tellp() > 0)
	{
		_ss << " AND ";
	}
	_ss << name << op << "'" << value << "'";
	return *this;
}
template<> inline Where& Where::AND(const string& name, const string& op, const char value)
{
	return this->AND(name, op, value);
}
template<> inline Where& Where::AND(const string& name, const string& op, const signed char value)
{
	return this->AND(name, op, value);
}
template<> inline Where& Where::AND(const string& name, const string& op, const unsigned char value)
{
	return this->AND(name, op, value);
}
Tnline Where& Where::OR(const string& name, const string& op, T value)
{
	if(_ss.tellp() > 0)
	{
		_ss << " OR ";
	}
	_ss << name << op << "'" << value << "'";
	return *this;
}
template<> inline Where& Where::OR(const string& name, const string& op, const char value)
{
	return this->OR(name, op, value);
}
template<> inline Where& Where::OR(const string& name, const string& op, const signed char value)
{
	return this->OR(name, op, value);
}
template<> inline Where& Where::OR(const string& name, const string& op, const unsigned char value)
{
	return this->OR(name, op, value);
}

#undef Tnline
